﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Clipping.Utils;
using System.IO;
using Clipping.Infrastructure.Models;
using BLToolkit.Data.Linq;
using System.Diagnostics.Contracts;
namespace Clipping.Utils
{
    public class UploadHistoryRepository
    {
        static DBConnectionPool dbConnectionPool;
        static UploadHistoryRepository()
        {
            string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DB", "history.db");
            dbConnectionPool = DBHelper.CreateDBConnectionPool<HistoryDBUpdater>(dbPath, 10);
        }


        public bool AddHistory(UploadHistory history)
        {
            Contract.Requires(history != null);
            Contract.Requires(!string.IsNullOrEmpty(history.Url));
            Contract.Requires(!string.IsNullOrEmpty(history.ClientId));
            using (var conn = dbConnectionPool.GetConnection())
            {
                var rtn = UPLOADHISTORY.Records.Insert(() => new UPLOADHISTORY
                {
                    ClientId = history.ClientId,
                    Url = history.Url.ToLower(),
                    Timestamp = DateTime.Now
                }) != 0;
                conn.Free();
                return rtn;
            }
        }

        public bool AddHistory(IEnumerable<UploadHistory> history)
        {
            using (var conn = dbConnectionPool.GetConnection())
            {
                foreach (var h in history)
                {
                    UPLOADHISTORY.Records.Insert(() => new UPLOADHISTORY
                   {
                       ClientId = h.ClientId,
                       Url = h.Url.ToLower(),
                       Timestamp = DateTime.Now
                   });
                }
                conn.Free();
            }
            return true;
        }

        public List<string> GetUploadedClients(string url)
        {
            Contract.Requires(!string.IsNullOrEmpty(url));
            using (var conn = dbConnectionPool.GetConnection())
            {

                var his = UPLOADHISTORY.Records.Where(r => r.Url == url.ToLower()).ToList();

                if (his != null && his.Count > 0)
                {
                    List<string> rtn = new List<string>();
                    foreach (var h in his)
                        rtn.Add(h.ClientId);

                    conn.Free();
                    return rtn;
                }
                else
                {
                    conn.Free();
                    return null;
                }
            }
        }

        public Dictionary<string, List<string>> GetUploadedClients(List<string> urls)
        {
            Contract.Requires(urls != null);
            Dictionary<string, List<string>> rtn = new Dictionary<string, List<string>>();

            using (var conn = dbConnectionPool.GetConnection())
            {
                foreach (var url in urls)
                {
                    var his = UPLOADHISTORY.Records.Where(r => r.Url == url.ToLower()).ToList();
                    if (his != null && his.Count > 0)
                    {
                        List<string> classIds = new List<string>();
                        foreach (var h in his)
                            classIds.Add(h.ClientId);
                        rtn[url] = classIds;
                    }
                    else
                    {
                        rtn[url] = null;
                    }
                }
                conn.Free();
            }
            return rtn;
        }

        public int DeleteExpiredRecords(DateTime time)
        {
            using (var conn = dbConnectionPool.GetConnection())
            {
                var rtn = UPLOADHISTORY.Records.Delete(r => r.Timestamp < time);
                conn.Free();
                return rtn;
            }
        }
    }

    public class OpenHistoryRepository
    {
        static DBConnectionPool dbConnectionPool;
        static OpenHistoryRepository()
        {
            string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DB", "history.db");
            dbConnectionPool = DBHelper.CreateDBConnectionPool<HistoryDBUpdater>(dbPath, 10);
        }

        public bool AddHistory(OpenHistory history)
        {
            Contract.Requires(history != null);
            Contract.Requires(!string.IsNullOrEmpty(history.Url));
            using (var conn = dbConnectionPool.GetConnection())
            {
                var rtn = OPENHISTORY.Records.Insert(() => new OPENHISTORY
                {
                    Url = history.Url.ToLower(),
                    Timestamp = DateTime.Now
                }) != 0;
                conn.Free();
                return rtn;

            }
        }

        public bool IsOpened(string url)
        {
            Contract.Requires(!string.IsNullOrEmpty(url));
            using (var conn = dbConnectionPool.GetConnection())
            {
                var rtn = OPENHISTORY.Records.Any(r => r.Url == url.ToLower());
                conn.Free();
                return rtn;
            }
        }
        public Dictionary<string, bool> IsOpened(List<string> urls)
        {
            Contract.Requires(urls != null);
            Contract.Requires(urls.Count > 0);
            Dictionary<string, bool> rtn = new Dictionary<string, bool>();
            using (var conn = dbConnectionPool.GetConnection())
            {
                foreach (var url in urls)
                {
                    bool isOpened = OPENHISTORY.Records.Any(r => r.Url == url.ToLower());
                    rtn[url] = isOpened;
                }
                conn.Free();
            }
            return rtn;
        }
        public int DeleteExpiredRecords(DateTime time)
        {
            using (var conn=dbConnectionPool.GetConnection())
            {
                var rtn= OPENHISTORY.Records.Delete(r => r.Timestamp < time);
                conn.Free();
                return rtn;
            }
        }

    }
}
